\chapter{Programming in Vorpal}
\label{Programming}

\section{Basics}

The most basic aspects of a language are sometimes not clearly listed.  Here are the core attributes of Vorpal:

\begin{itemize}
\item names are case-sensitive, so \verb-A- and \verb-a- are different names
\item spacing within a line does not matter
\item binding is completely dynamic
\item no semicolons, single expression per line
\item all methods have a return value (\verb-self- is returned if the \verb-return- statement is not used)
\item the only form of comment starts with \verb-#- and runs to the end of the line
\item no operator precedence; left-to-right precedence
\item no logical expression shortcutting; \verb-( 1==0 && a.f() )- will send message, \verb-f- to \verb-a-
\item strings are delimited with single or double quotes, \verb-'like this'- or \verb-"like this"-
\end{itemize}

\section{Objects, Messages, and Methods}

In a nutshell, Vorpal is a scripting language where Objects respond to Messages by executing code defined in Methods.  In fact, {\em all} Vorpal code is executed by sending a message to an object.   

All Vorpal values are fully dynamic objects Objects (even numbers).  Objects contain slots associating a key value, with an Object stored in the slot.  For instance, \verb-a.x = 10- is setting the \verb-x- slot of \verb-a- to contain \verb-10-.  In general, slots may be accessed using any object as a key using the \verb-[ ]- syntax:  \verb-a[b]-.  The dot syntax is shorthand for indexing using a string, so these two forms are equivalent (as in Lua): \verb-a.x- and \verb-a['x']-. 

There are no classes in Vorpal.  Each object in the system can be augmented with any number of data values or methods, which are attached to the object in named or indexed slots.  When a message is sent to an object it invokes a method slot of the same name.  An implicit \verb-self- parameter is passed to all methods, and the only way to call a method is to send a message to an object (there are no functions in Vorpal).  Methods are defined with the following syntax: \verb-method(arg1, arg2){ }- 

The \verb-new- keyword creates objects.  If no parameters are passed to \verb-new-, then an empty characterless object is created.  Passing parameters to new is used to create clones of existing objects, see section \ref{cloning_section}.  Let's look at defining an object with the classic "hello world" method:

\vorpal
x = new()
x.hello = method(){ 'Hello, World'.print() }
x.hello()
\end{lstlisting} 

\begin{enumerate}
\item defines a new object
\item sets the \verb-hello- slot in \verb-x- to a method
\item sends \verb-x- the \verb-hello- message, which will result in "Hello, World" being printed.
\end{enumerate}

\section{Methods: self and sys}

Within the method that is called to respond to a message, the receiving object is called \verb-self-. Vorpal is dynamically scoped (meaning all lookup happens at run-time) and there is no global scope.  There is a global object called, \verb-sys-, but it may in fact point to a different Object at different times (usually because the host program has determined that a different system component is appropriate).

Essentially, there are {\em two} implicit parameters passed to each method: \verb-self- and \verb-sys-.  Vorpal code determines what \verb-self- is by sending messages to Object: \verb-self- is always the receiver of the message.  The host application determines what the \verb-sys- object is by passing it to the virtual machine when code is executed.  At a minimum it will contain references to \verb-number-, \verb-string-, and \verb-object-.  Let's look at an example:

\vorpal
a = 10
a.much_bigger = method(b){
    return(self > (2*b))
}

if( a.much_bigger(4) ){
	'much greater than 4'.print()
}
if( a.much_bigger(5) ){
	'much greater than 5'.print()
}
\end{lstlisting} 

\subsection{Variable Length Parameter List}
Each method can have a variable-length parameter (VPL), indicated by \verb-[ ]- after the parameter name.  The VLP (if present) will be replaced with an array containing all the extra arguments passed to the method.  Effectively, extra arguments are absorbed into the array.  Calling the function with fewer parameters than needed is still a runtime error.  The VPL may be omitted, which will result in an empty array as the value of that parameter.

\vorpal
self.f = method(x, y[ ], z){
	x.print()
	for(i = 0, i < y.size(), i = i + 1){
		('[' + y[i] + ']').print()
	}
	z.print()
}

self.f(1, 2, 3)
'---'.print()
self.f(1, 2, 3, 4)
'---'.print()
self.f(1, 2)
\end{lstlisting} 

\begin{verbatim}
Output:
1
[2]
3
---
1
[2]
[3]
4
---
1
2
\end{verbatim}

\subsection{Implicit Self}

Wherever you use \verb-self- to access a slot using the \verb-self.name- or \verb-self[key]- syntax, you can omit the \verb-self- keyword.  This feature is simply an option to reduce typing or reduce redundancy in the code.  For example consider the following method definitions which are completely equivalent:

\vorpal
self.f = method(){ 
	self.print() 
	self[1] = self.x
}

.f = method(){ 
	.print() 
	[1] = .x
}
\end{lstlisting} 

\section{Message Lookup}

Knowing exact order of method lookup is only occasionally necessary.  A handler for messages is looked for in the following places (the first match is used).

\begin{enumerate}
\item in the C++ object handler for the object type
\item in the object itself
\item in delegates of the object
\item in sys.TYPE, where type matches the object type (\verb-number-, \verb-string-, and \verb-object-)
\end{enumerate}

\noindent Slot lookup for getting or setting slots looks only in \#2 and \#3; meaning, that C++ handlers and the sys.TYPE are not allowed to define data slots.  Delegates are a way of installing proxy objects which will automatically fill in when a message or slot is missing.  The \verb-delegate- slot can either be a single object or an array of objects (which are searched in numerical order).
\vorpal
a = new()
a.f = method(){
        .x.print()
}

d = new()
d.delegate = a
d.x = 7
d.f() # prints 7
\end{lstlisting} 

\section{Operators}

Vorpal allows you to define operators.  In fact, all operators are actually messages, such that \verb-a > b- is effectively \verb-a.>(b)-, and \verb-!a- is \verb-a.!()-.  Both unary and binary operators are automatically supported.  Note, you cannot have a unary and binary message with the same name, and you can't explicitly call operator messages with the \verb-.- notation.  All names that contain punctuation characters are parsed as operator messages, except the following which cannot be part of operators: \verb-{ } ( ) [ ] , .-

\vorpal
a = 10
a.>> = method(b){
    return(self > (2*b))
}

a.!! = method(){
    return (self != none)
}

if( a >> 4 ){
        'much greater than 4'.print()
}
if( a >> 5 ){
        'much greater than 5'.print()
}
if( !!a ){
        'not none'.print()
}
\end{lstlisting} 

\section{Data Types}

The various data types supplied in the core of Vorpal are described in the following sections.  The host application may easily supply additional object types, but those will have to be documented else where.

\subsection{Objects}

Some objects in Vorpal are undifferentiated and are simply called Objects.  All other data types share the basic capabilities of Objects.  In addition to slots and methods defined in \verb-sys.object-, the following methods are available to all objects: \\

\begin{itemize}

\item \verb-self.apply(fcn, ...)-: Execute \verb-fcn- as if it was a method of \verb-self- passing the remaining arguments as parameters.  The effect is as if the following was executed:
\vorpalshort
self.f = fcn
self.f(...)
self.f = none
\end{lstlisting} 

\item \verb-self.map(fcn, ...)-: Apply \verb-fcn- to each array slot {\em value} of \verb-self- passing the remaining arguments as parameters.  The effect is as if the following pseudo-code was executed:
\vorpalshort
for(value in self.array){
   value.apply(fcn, ...)
}
\end{lstlisting} 

\item \verb-self.size()-: Number of array slots in \verb-self-. \\

\item \verb-self.append(obj)-: Append \verb-obj- to array slots in \verb-self-. As if the following was executed:
\vorpalshort
self[self.size()] = obj
\end{lstlisting}

\item \verb-self.load(path, ...)-: Apply method defined in the file at \verb-path- to \verb-self-. \\

\item \verb-self.fill(start, end, delta, value)-:  Set all numerical indices from \verb-start- to \verb-end- of \verb-self- to \verb-value-, as if the following was executed:
\vorpalshort
for(i = start, i < end, i = i + delta){
    [i] = value
}
\end{lstlisting} 

\item \verb-self.print()-: Print string form of \verb-self- followed by a newline. \\

\item \verb-self.put()-: Print string form of \verb-self- \\

\item \verb-self && other-: \verb-true- iff neither object is \verb-none- nor \verb-false- \\

\item \verb-self || other-: \verb-true- iff one object is not \verb-none- and not \verb-false- \\

\item \verb-!self-: \verb-true- iff \verb-self- is  \verb-none- and not \verb-false- \\

\item \verb-self == other-: \verb-true- iff \verb-self- and not \verb-other- are the same object \\

\item \verb-self != other-: \verb-true- iff \verb-self- and not \verb-other- are {\em not} the same object 

\end{itemize} 

\subsection{Methods and Closures}

Methods are somewhat unusual types.  They are full objects with slots and can be sent messages themselves, but mostly they are used simply to handle messages sent to the object they are attached to.  When a method is executing it can access its own slots using the \verb-code- keyword.  No additional messages are defined by Method objects.

\vorpal
# first example, defines a closure that adds to a slot by name
# ------------------------------------------------------------
.make_adder = method(key, delta){
    f = method(){
        # recall implicit self, [key] == self[key]
        [code.key] = [code.key] + code.delta 
    }
    f.key = key # store the closure values
    f.delta = delta
    return( f )
}

x = new()
x.val = 4
x.plus3 = .make_adder('val', 3)
x.val.print() # output: 4
x.plus3()
x.val.print() # output: 7

# second example, defines a search in an array
# ------------------------------------------------------------
array = new()
for(i = 0, i < 10, i = i + 1){ # setup
    array[i] = 2*i
}

array.find = method(target){
    for(i = 0, [i], i = i + 1){ # for each valid index
        if([i] == target){
            i.print()
        }
    }
}

array.find(4) # output: 2

array.find_maker = method(target){
    f = method(){
        return( .find(code[0]) )
    }
    f[0] = target
    return(f)
}

array.find10 = array.find_maker(10)
array.find10() # output: 5
\end{lstlisting}

\subsection{System}

The System object is also unusual.  It's functionality is almost entirely determined by the host application.  However, it does define a number of data slots allowing Methods to access behaviour defined for object types:

\begin{itemize}
\item \verb-sys.number-
 
\item \verb-sys.string-
 
\item \verb-sys.object-
\end{itemize}

\subsection{True, False, and None}

True and False are globally unique Objects identified with true and false boolean states.  They can be accessed by \verb-true- and \verb-false-.  

A final globally unique object, \verb-none-, is returned when when a slot or result is undefined.  When used as a boolean, \verb-none- behaves the same as \verb-false-.

\subsection{Numbers}

Vorpal Numbers are double precision floating point values.  The values compiled into byte-code are single precision to save space.

\noindent Binary operators combining two Numbers to produce another Number:

\verb@ - + * / ^ \% @

\noindent Binary operators combining two Numbers to produce a Boolean:

\verb@ == != < > <= >= @

\noindent Unary messages producing another Number:

\verb@ abs, floor, ceil, round, exp, log, log10, sqrt @

\verb@ sin, cos, tan, invsin, invcos, invtan @

\subsection{Strings}

Strings are not too surprising.  The first index is zero and the \verb-end- index in the methods below is not included in the range of indices.  Strings can be delimited by either single or double quotes.

\begin{itemize}
\item \verb-self.find(str, [start, [end]])-

\item \verb-self.strcmp(str)-

\item \verb-self.substring(start, [end])-

\item \verb-self.left()-

\item \verb-self.number()-

\item \verb-self.length()-

\item \verb-self + other-

\item \verb-self == other-

\item \verb-self != other-
\end{itemize}

\subsubsection{Console Input}

Strings may be read from the command line using the string object's \verb@input@ method.

\vorpal
# read a string from console without specifying an input prompt
x = ''.input()
x.print()
    
# read a string from console with an input prompt
fingers = 'How many fingers do you have in total?'.input().number()
('You might have ' + (fingers / 2) + ' fingers on each hand').print()
\end{lstlisting}

An input prompt is specified by placing a non-zero-length string as the receiver to the \verb@input@ method. If no input prompt is specified then Vorpal will use a greater-than sign followed by a single space to prompt the user. \\

\noindent When an input prompt is specified Vorpal will place a single space after the end of the prompt for clarity.\\ 

\noindent The code snippet above will produce the following output.

\begin{verbatim}
    $ bin/vorpal examples/input.vorpal 
    Vorpal
    -----------
    > test
    test
    How many fingers do you have in total? 10
    You should have 5 fingers on each hand
    ----------
\end{verbatim}

\subsection{Files}

A file object can be used to read or write files. To create a file for writing data 
to, use a string to represent the path to the file:

\verb@ f = 'path'.open('write') @

\noindent Any data already in the file will be deleted if it is opened in write mode.
To read data from a file, open it in read mode:

\verb@ f = 'path'.open('read') @

\noindent Individual lines can be written or read (depending on the mode the file was opened in).
The file can be closed once file operations are complete.

\begin{itemize}
\item \verb-self.read()-

\item \verb-self.write(str)-

\item \verb-self.close()-

\end{itemize}

\section{Conditionals}

A fairly normal \verb@if-elseif-else@ clause is the only conditional Vorpal has.  The \verb-elseif- and \verb-else- parts of the conditional are optional.

\section{Loops}

Vorpal has \verb-while- and \verb-for- loops.  The are both similar to their C++ counterparts, except that commas are used to separate the parts of a \verb-for- loop.  The \verb-break- keyword can be used to break out of loops.

\section{Cloning}
\label{cloning_section}
New objects can be created by cloning an existing object using \verb-new-.  The cloned object is exactly like the original, they share {\em all} internal references.  If the object has a \verb-created- method, it will be called on the newly created object immediately after creation (this allows the object to change any references that should not be shared).

\vorpal
a = new()
a.x = 0
a.created = method(initial){
    .x = initial
}

b = new(a, 7)
b.x.print() # prints 7
a.x.print() # prints 0
\end{lstlisting}

\section{Examples}

\subsection{Simple, Iterative Fibonacci}

\vorpal
sys.number.fib = method(){ # add Fibonacci to all numbers
    result = 1
    prev = 1
    for(i = 3, i <= self, i=i+1){
        tmp = prev + result
        prev = result
        result = tmp
    }           
    return(result)
}

if(sys.argCount < 1){
    'Usage: fib.vorpal limit'.print()
}
else{
    limit = sys.arg(0).number()
    for(i = 0, i < limit, i=i+1){ # print a table of Fibonacci numbers
        ('' + i + '\t' + i.fib()).print()
    }
}
\end{lstlisting} 
